package br.com.sovi.resources;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;

import com.sun.jersey.spi.spring.container.servlet.SpringServlet;

public class RequestMockHttpServletBuilder {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	private final static String contextPath = "/glomer-server/rest";

	private final MockHttpServletRequest request;

	private final StringBuilder content;

	private String uniqueContent;

	public RequestMockHttpServletBuilder(final MockServletContext servletContext, final HttpMethod method, final String path) {
		this.request = new MockHttpServletRequest(servletContext, method.toString(), contextPath + path);
		this.request.setContextPath(contextPath);

		this.content = new StringBuilder();
	}

	public RequestMockHttpServletBuilder contentType(final String contentType) {
		addHeader("Content-Type", contentType);
		return this;
	}

	public RequestMockHttpServletBuilder addContent(final String key, final String value) {
		this.content.append("&").append(key).append("=").append(value);
		return this;
	}

	public MockHttpServletResponse buildResponse(final SpringServlet dispatcher) {
		if (this.uniqueContent == null) {
			if (this.content.toString().length() > 0) {
				this.uniqueContent = this.content.toString().substring(1);
				this.request.setContent(this.uniqueContent.getBytes());
			}
		} else {
			this.request.setContent(this.uniqueContent.getBytes());
		}

		this.logger.debug(String.format("Content        : %s", this.uniqueContent));
		this.logger.debug(String.format("Content Length : %s", this.request.getContentLength()));
		this.logger.debug(String.format("Content Type   : %s", this.request.getContentType()));
		this.logger.debug(String.format("Request URI    : %s", this.request.getRequestURI()));
		this.logger.debug(String.format("Method         : %s", this.request.getMethod()));
		this.logger.debug(String.format("Context Path   : %s", this.request.getContextPath()));

		final Enumeration<?> headerNomes = this.request.getHeaderNames();
		while (headerNomes.hasMoreElements()) {
			final Object nextElement = headerNomes.nextElement();
			this.logger.debug(String.format("Header : %s = %s", nextElement.toString(), this.request.getHeader(nextElement.toString())));
		}
		final Enumeration<?> parameterNomes = this.request.getParameterNames();
		while (parameterNomes.hasMoreElements()) {
			final Object nextElement = parameterNomes.nextElement();
			this.logger.debug(String.format("Parameter : %s = %s", nextElement.toString(), this.request.getHeader(nextElement.toString())));
		}

		final MockHttpServletResponse response = new MockHttpServletResponse();

		try {
			dispatcher.service(this.request, response);
		} catch (final ServletException e) {
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		}

		return response;
	}

	public RequestMockHttpServletBuilder setContent(final String content) {
		this.uniqueContent = content;
		return this;
	}

	public RequestMockHttpServletBuilder addHeader(final String nome, final String value) {
		this.request.addHeader(nome, value);
		return this;
	}

	public RequestMockHttpServletBuilder addParameter(final String nome, final String value) {
		this.request.addParameter(nome, value);
		return this;
	}

}
